package com.iplant.pdm.serviceImpl.dao.fpc;

import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.utils.annotation.dao.DBBaseDAO;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.base.utils.sql.orm.PoService;
import com.iplant.pdm.service.po.bop.FPCRoute;
import com.iplant.pdm.service.po.bop.FPCRoutePart;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.pdm.service.po.bop.FPCRoutePartPoint;
import com.iplant.pdm.service.po.fpc.flow.FPCFlowLine;
import com.iplant.pdm.service.po.fpc.flow.FPCFlowPart;
import com.iplant.pdm.service.po.fpc.flow.FPCFlowPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.stream.Collectors;


@DBBaseDAO(FPCRoute.class)
public class FPCRouteDAO extends BaseDAO {

    private static Logger logger = LoggerFactory.getLogger(FPCRouteDAO.class);
    private static FPCRouteDAO Instance = null;

    private FPCRouteDAO() {
        super("");
        this.Init();
    }

    public static FPCRouteDAO getInstance() {
        if (Instance == null) Instance = new FPCRouteDAO();
        return Instance;
    }

    /**
     * 自身除开的最大版本号
     *
     * @param wLoginUser
     * @param wName
     * @param wErrorCode
     * @return
     */
    private int FPC_GetMaxVersion(BMSEmployee wLoginUser, String wName, OutResult<Integer> wErrorCode) {

        int wMaxVersion = 0;
        wErrorCode.set(0);

        try {

            String wSQLText = StringUtils.Format("select Max(SUBSTRING_INDEX(t.Code,CONCAT(t.Name,''.V_''),-1)+0 ) as" +
                    " ItemCount ,t.Name" + "  from  {0}.fpc_route t where locate(t.Name,t.Code)=1 and t.Name=:Name " +
                    "group by Name ;", super.getDBName());

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("Name", wName);

            List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams);

            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                wMaxVersion = StringUtils.parseInt(wSqlDataReader.get("ItemCount"));
            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());

            logger.error("FPC_UpdateRoute", ex);
        }
        return wMaxVersion;
    }

    public synchronized void FPC_UpdateRoute(BMSEmployee wLoginUser, FPCRoute wRoute, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {

            if (wRoute == null || wRoute.ProductID <= 0 || StringUtils.isEmpty(wRoute.Name)) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }

            FPCRoute wRouteO = this.FPC_QueryRoute(wLoginUser, 0, wRoute.Code, wErrorCode);
            if (wRouteO.ID > 0 && wRouteO.ID != wRoute.ID) {
                wErrorCode.set(ExceptionTypes.Duplication.getValue());
                return;
            }

            if (wRoute.ID <= 0 || !wRoute.Code.startsWith(wRoute.Name)) {

                int wVersion = this.FPC_GetMaxVersion(wLoginUser, wRoute.Name, wErrorCode);

                wRoute.Code = StringUtils.Format("{0}.V_{1}", wRoute.Name, String.format("%04d", wVersion + 1));
            }

            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("Name", wRoute.Name);
            wParams.put("Code", wRoute.Code);
            wParams.put("LineID", wRoute.LineID);
            wParams.put("ProductID", wRoute.ProductID);
            wParams.put("CustomerID", wRoute.CustomerID);
            wParams.put("Description", wRoute.Description);
            wParams.put("IsStandard", wRoute.IsStandard);
            wParams.put("Active", wRoute.Active);
            wParams.put("EditTime", Calendar.getInstance());
            wParams.put("EditorID", wLoginUser.getID());

            if (wRoute.ID <= 0) {

                wParams.put("CreateTime", Calendar.getInstance());
                wParams.put("CreatorID", wLoginUser.getID());

                wRoute.ID = super.Insert(super.getTableName("fpc_route"), wParams);

            } else {
                wParams.put("ID", wRoute.ID);

                super.Update(super.getTableName("fpc_route"), "ID", wParams);
            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());

            logger.error("FPC_UpdateRoute", ex);
        }
    }

    public void FPC_SetRouteToStandard(BMSEmployee wLoginUser, int wID, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);
        // 判断客户信息是否存在(中国：统一社会信用代码，国外:提醒是否有重复）

        try {
            if (wID <= 0) return;

            FPCRoute wFPCRoute = this.FPC_QueryRoute(wLoginUser, wID, wErrorCode);
            if (wFPCRoute == null || wFPCRoute.ID <= 0 || wFPCRoute.Active != 1) return;

            Map<String, Object> wParams = new HashMap<String, Object>();
            String wSQLText = StringUtils.Format("update {0}.fpc_route set IsStandard=0 where LineID =:LineID" + " " +
                            "and  ProductID =:ProductID  and  CustomerID =:CustomerID" + " and IsStandard=1 ;",
                    super.getDBName());

            wParams.put("ID", wFPCRoute.ID);
            wParams.put("LineID", wFPCRoute.LineID);
            wParams.put("ProductID", wFPCRoute.ProductID);
            wParams.put("CustomerID", wFPCRoute.CustomerID);

            wSQLText = this.DMLChange(wSQLText);
            super.update(wSQLText, wParams);

            wSQLText = StringUtils.Format(" update {0}.fpc_route set IsStandard=1 where ID=:ID and Active = 1 ; ",
                    super.getDBName());
            wParams.clear();
            wParams.put("ID", wFPCRoute.ID);
            wSQLText = this.DMLChange(wSQLText);
            super.update(wSQLText, wParams);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FPC_SetRouteToStandard", ex);
        }
    }

    public void FPC_DeleteRoute(BMSEmployee wLoginUser, FPCRoute wRoute, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {

            if (wRoute == null || wRoute.ID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }

            Map<String, Object> wParams = new HashMap<String, Object>();

            String wSQLText = StringUtils.Format("Delete from {0}.fpc_route  Where ID=:ID AND Active=0;",
                    super.getDBName());

            wParams.put("ID", wRoute.ID);
            wSQLText = this.DMLChange(wSQLText);
            int wRow = super.update(wSQLText, wParams);
            if (wRow > 0) {


                wSQLText =
                        StringUtils.Format("Delete t from {0}.fpc_routepartpoint t,{0}.fpc_routepart t1  Where t1" +
                                ".ID>0 and t.ID>0 and t.RoutePartID=t1.ID AND t1.RouteID=:ID ;", super.getDBName());

                super.update(wSQLText, wParams);


                wSQLText = StringUtils.Format("Delete from {0}.fpc_routepart  Where ID>0 AND RouteID=:ID ;",
                        super.getDBName());
                super.update(wSQLText, wParams);
            }

        } catch (Exception ex) {

            wErrorCode.set(ExceptionTypes.DBSQL.getValue());

            logger.error("FPC_DeleteMOM", ex);
        }
    }

    public void FPC_ActiveRoute(BMSEmployee wLoginUser, FPCRoute wRoute, int wActive, OutResult<Integer> wErrorCode) {
        wErrorCode.set(0);

        try {
            if (wRoute == null || wRoute.ID <= 0) {
                wErrorCode.set(ExceptionTypes.Parameter.getValue());
                return;
            }
            Map<String, Object> wParams = new HashMap<String, Object>();

            String wSQLText = StringUtils.Format("Update {0}.fpc_route Set Active=:Active,EditorID=:EditorID," +
                    "EditTime=now() Where ID=:ID", super.getDBName());

            wParams.put("Active", wActive == 1 ? wActive : 2);
            wParams.put("EditorID", wLoginUser.getID());
            wParams.put("ID", wRoute.ID);
            wSQLText = this.DMLChange(wSQLText);
            super.update(wSQLText, wParams);
        } catch (Exception ex) {

            wErrorCode.set(ExceptionTypes.DBSQL.getValue());

            logger.error("FPC_ActiveRoute", ex);
        }
    }

    public List<FPCRoute> FPC_QueryRouteList(BMSEmployee wLoginUser, String wName, String wCodeLike, int wFactoryID,
                                             int wLineID, int wCustomerID, int wProductTypeID, int wProductID,
                                             String wProductNo, int wTypeID, int wActive, int wIsStandard,
                                             int wHasItem, Pagination wPagination, OutResult<Integer> wErrorCode) {

        return this.FPC_QueryRouteList(wLoginUser, -1, "", wName, wCodeLike, wFactoryID, wLineID, wCustomerID,
                wProductTypeID, wProductID, wProductNo, wTypeID, wActive, wIsStandard, wHasItem, wPagination,
                wErrorCode);

    }

    private List<FPCRoute> FPC_QueryRouteList(BMSEmployee wLoginUser, int wID, String wCode, String wName,
                                              String wCodeLike, int wFactoryID, int wLineID, int wCustomerID,
                                              int wProductTypeID, int wProductID, String wProductNo, int wTypeID,
                                              int wActive, int wIsStandard, int wHasItem, Pagination wPagination,
                                              OutResult<Integer> wErrorCode) {
        List<FPCRoute> wRouteList = new ArrayList<FPCRoute>();
        wErrorCode.set(0);

        try {

            // Step02:查询
            Map<String, Object> wParams = new HashMap<String, Object>();

            String wSQLText = StringUtils.Format("Select t.*,t1.FactoryID,t1.Name as LineName,t1.Code as LineCode, t2" +
                    ".Name as FactoryName," + " t2.Code as FactoryCode,t3.Name as CustomerName, t3.Code as " +
                    "CustomerCode, " + " t4.Name as CreatorName, t5.Name as EditorName,t6.Name as  ProductName ," +
                    " t6.Code as  ProductNo ,t6.ProductTypeID, t7.Name as ProductTypeName," + " t7.Code as " +
                    "ProductTypeCode,count(t8.ID) as  ItemCount from {1}.fpc_route t" + " left join {1}" +
                    ".fpc_routeparent t9 on t.BOPParentID=t9.ID " + " left join {0}.fmc_line t1 on t9.LineID=t1.ID " + " left join {0}.fmc_factory t2 on t9.FactoryID=t2.ID " + " left join {0}.crm_customer t3 on t9.CustomerID=t3.ID " + " left join {0}.mbs_user t4 on t.CreatorID=t4.ID " + " left join {0}.mbs_user t5 on t.EditorID=t5.ID" + " left join {1}.fpc_product t6 on t9.ProductID=t6.ID" + " left join {1}.fpc_producttype t7 on t6.ProductTypeID=t7.ID " + " left join {1}.fpc_routepart t8 on t.ID=t8.RouteID" + " where (:ID<=0 or t.ID=:ID) and (:Name = '''' or :Name = t.Name) " + " and (:Code = '''' or :Code = t.Code)  and  (:TypeID<=0 or t.TypeID=:TypeID) " + " and (:LineID<=0 or :LineID = t9.LineID) " + " and (:FactoryID<=0 or :FactoryID = t9.FactoryID)" + " and (:CustomerID<0 or :CustomerID = t9.CustomerID)" + " and (:ProductTypeID<=0 or :ProductTypeID = t6.ProductTypeID) " + " and (:ProductID<=0 or :ProductID = t9.ProductID) " + " and (:Active< 0 or :Active = t.Active) " + " and (:IsStandard< 0 or :IsStandard = t.IsStandard) " + " and (:ProductNo = '''' or :ProductNo = t6.Code) " + " and (:CodeLike = '''' or  t.Code like :CodeLike) group by t.ID", super.getDBName(), DBSchemas.PDM.getDBName());

            wSQLText = this.DMLChange(wSQLText);

            wParams.put("ID", wID);
            wParams.put("Name", wName);
            wParams.put("Code", wCode);
            wParams.put("FactoryID", wFactoryID);
            wParams.put("LineID", wLineID);
            wParams.put("ProductTypeID", wProductTypeID);
            wParams.put("ProductID", wProductID);
            wParams.put("Active", wActive);
            wParams.put("IsStandard", wIsStandard);
            wParams.put("ProductNo", wProductNo);
            wParams.put("CustomerID", wCustomerID);
            wParams.put("TypeID", wTypeID);
            wParams.put("CodeLike", wCodeLike);

            List<Integer> wRouteID = new ArrayList<Integer>();
            List<Map<String, Object>> wQueryResultList = super.queryForList(wSQLText, wParams, wPagination);
            for (Map<String, Object> wSqlDataReader : wQueryResultList) {
                FPCRoute wRoute = new FPCRoute();
                wRoute.ID = StringUtils.parseInt(wSqlDataReader.get("ID"));
                wRoute.Code = StringUtils.parseString(wSqlDataReader.get("Code"));
                wRoute.Name = StringUtils.parseString(wSqlDataReader.get("Name"));
                wRoute.Version = StringUtils.parseString(wSqlDataReader.get("Version"));
                wRoute.TypeID = StringUtils.parseInt(wSqlDataReader.get("TypeID"));
                wRoute.FactoryID = StringUtils.parseInt(wSqlDataReader.get("FactoryID"));
                wRoute.FactoryCode = StringUtils.parseString(wSqlDataReader.get("FactoryCode"));
                wRoute.FactoryName = StringUtils.parseString(wSqlDataReader.get("FactoryName"));
                wRoute.ProductTypeID = StringUtils.parseInt(wSqlDataReader.get("ProductTypeID"));
                wRoute.ProductTypeCode = StringUtils.parseString(wSqlDataReader.get("ProductTypeCode"));
                wRoute.ProductTypeName = StringUtils.parseString(wSqlDataReader.get("ProductTypeName"));
                wRoute.LineID = StringUtils.parseInt(wSqlDataReader.get("LineID"));
                wRoute.LineName = StringUtils.parseString(wSqlDataReader.get("LineName"));
                wRoute.LineCode = StringUtils.parseString(wSqlDataReader.get("LineCode"));
                wRoute.ProductID = StringUtils.parseInt(wSqlDataReader.get("ProductID"));
                wRoute.ProductNo = StringUtils.parseString(wSqlDataReader.get("ProductNo"));
                wRoute.ProductName = StringUtils.parseString(wSqlDataReader.get("ProductName"));
                wRoute.CustomerID = StringUtils.parseInt(wSqlDataReader.get("CustomerID"));
                wRoute.CustomerCode = StringUtils.parseString(wSqlDataReader.get("CustomerCode"));
                wRoute.CustomerName = StringUtils.parseString(wSqlDataReader.get("CustomerName"));

                wRoute.ItemCount = StringUtils.parseInt(wSqlDataReader.get("ItemCount"));
                wRoute.IsStandard = StringUtils.parseInt(wSqlDataReader.get("IsStandard"));
                wRoute.Active = StringUtils.parseInt(wSqlDataReader.get("Active"));
                wRoute.CreatorID = StringUtils.parseInt(wSqlDataReader.get("CreatorID"));
                wRoute.EditorID = StringUtils.parseInt(wSqlDataReader.get("EditorID"));
                wRoute.CreatorName = StringUtils.parseString(wSqlDataReader.get("CreatorName"));
                wRoute.EditorName = StringUtils.parseString(wSqlDataReader.get("EditorName"));
                wRoute.CreateTime = StringUtils.parseCalendar(wSqlDataReader.get("CreateTime"));
                wRoute.EditTime = StringUtils.parseCalendar(wSqlDataReader.get("EditTime"));

                wRoute.Description = StringUtils.parseString(wSqlDataReader.get("Description"));
                wRouteList.add(wRoute);
                if (!wRouteID.contains(wRoute.ID)) wRouteID.add(wRoute.ID);
            }

            if (wHasItem == 1) {
                List<FPCRoutePart> wRoutePartList = FPCRoutePartDAO.getInstance().FPC_QueryRoutePartList(wLoginUser,
                        wRouteID, "", "", "", -1, wHasItem, Pagination.getMaxSize(), wErrorCode);
                if (wRoutePartList == null || wRoutePartList.size() == 0) return wRouteList;

                Map<Integer, List<FPCRoutePart>> wRoutePartDic =
                        wRoutePartList.stream().collect(Collectors.groupingBy(p -> p.RouteID));

                for (FPCRoute fpcRoute : wRouteList) {
                    if (fpcRoute == null || fpcRoute.ID <= 0 || !wRoutePartDic.containsKey(fpcRoute.ID)) continue;

                    fpcRoute.PartList = wRoutePartDic.get(fpcRoute.ID);
                }

            }
            // Step03:配置系统

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.DBSQL.getValue());
            logger.error("FPC_QueryRouteList", ex);
        }
        return wRouteList;
    }

    public FPCRoute FPC_QueryRoute(BMSEmployee wLoginUser, int wID, OutResult<Integer> wErrorCode) {
        FPCRoute wResult = new FPCRoute();

        Map<String, Object> wParams = new HashMap<String, Object>();
        wParams.put("ID", wID);
        List<FPCRoute> wFPCRouteList = this.SelectPOList(wLoginUser, wParams, FPCRoute.class, Pagination.getMaxSize(),
                wErrorCode);
        if (wFPCRouteList != null && wFPCRouteList.size() > 0) {

            wResult = wFPCRouteList.get(0);

            wParams.clear();
            wParams.put("RouteID", wID);
            wResult.PartList = FPCRoutePartDAO.getInstance().SelectPOList(wLoginUser, wParams,
                    Pagination.getMaxSize(), wErrorCode);

            List<FPCRoutePartPoint> wFPCRoutePartPointList = FPCRoutePartPointDAO.getInstance().SelectPOList(wLoginUser,
                    wParams, Pagination.getMaxSize(), wErrorCode);

            for (FPCRoutePart wFPCRoutePart : wResult.PartList) {
                wFPCRoutePart.PartPointList =
                        wFPCRoutePartPointList.stream().filter(p -> p.RoutePartID == wFPCRoutePart.ID).collect(Collectors.toList());
            }
        }

        return wResult;

    }

    public FPCRoute FPC_QueryRoute(BMSEmployee wLoginUser, String wCode, OutResult<Integer> wErrorCode) {

        return this.FPC_QueryRoute(wLoginUser, -1, wCode, wErrorCode);

    }

    public FPCRoute FPC_QueryRoute(BMSEmployee wLoginUser, int wID, String wCode, OutResult<Integer> wErrorCode) {
        FPCRoute wRoute = new FPCRoute();
        try {
            if (wID <= 0 && StringUtils.isEmpty(wCode)) return wRoute;

            List<FPCRoute> wFPCRouteList = this.FPC_QueryRouteList(wLoginUser, wID, wCode, "", "", -1, -1, -1, -1, -1
                    , "", -1, -1, -1, 1, Pagination.getDefault(), wErrorCode);
            if (wFPCRouteList != null && wFPCRouteList.size() > 0) {
                wRoute = wFPCRouteList.get(0);
                //赋值PartList
                PoService<FPCRoutePart> wFPCRoutePartService = ORMUtils.GetPoService(FPCRoutePart.class);
                Map<String, Object> wParams = new HashMap<String, Object>();
                wParams.put("RouteID", wRoute.ID);
                wParams.put("Active", 1);
                wRoute.PartList = wFPCRoutePartService.SelectPOList(wLoginUser, wParams, Pagination.getMaxSize(),
                        wErrorCode);


            }

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.Exception.getValue());
            logger.error("FPC_QueryRoute", ex);
        }
        return wRoute;
    }

    public FPCRoute FPC_QueryRouteStandard(BMSEmployee wLoginUser, int wFactoryID, int wLineID, int wCustomerID,
                                           int wProductID, OutResult<Integer> wErrorCode) {
        FPCRoute wRoute = new FPCRoute();
        try {

            if (wProductID <= 0) return wRoute;


            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("LineID", wLineID);
            wParams.put("FactoryID", wFactoryID);
            wParams.put("CustomerID", wCustomerID);
            wParams.put("ProductID", wProductID);
            wParams.put("Active", 1);
            wParams.put("IsStandard", 1);
            List<FPCRoute> wFPCRouteList = this.SelectPOList(wLoginUser, wParams, Pagination.getDefault(), wErrorCode);


            if (wFPCRouteList != null && wFPCRouteList.size() > 0) wRoute = wFPCRouteList.get(0);

        } catch (Exception ex) {
            wErrorCode.set(ExceptionTypes.Exception.getValue());
            logger.error("FPC_QueryRoute", ex);
        }
        return wRoute;
    }

    public Map<Integer, Integer> FPC_QueryRouteSonMap(BMSEmployee wLoginUser, List<Integer> wRouteIDList,
                                                      OutResult<Integer> wErrorCode) {
        Map<Integer, Integer> wResult = new HashMap<>();
        try {
            if (wRouteIDList == null || wRouteIDList.size() == 0) {
                return wResult;
            }

            String wSQL = StringUtils.Format("SELECT RouteID,count(*) FQTY FROM {0}.fpc_routepart where " + "RouteID " +
                    "in ({1}) group by RouteID;", DBSchemas.PDM.getDBName(), StringUtils.Join(",", wRouteIDList));

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wSQL = this.DMLChange(wSQL);

            List<Map<String, Object>> wQueryResult = this.queryForList(wSQL, wParamMap);

            for (Map<String, Object> wReader : wQueryResult) {
                int wRouteID = StringUtils.parseInt(wReader.get("RouteID"));
                int wFQTY = StringUtils.parseInt(wReader.get("FQTY"));
                wResult.put(wRouteID, wFQTY);
            }
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
        return wResult;
    }

    public List<FPCFlowPart> GetFlowPartList(List<FPCRoutePart> wRoutePartList) {
        List<FPCFlowPart> wResult = new ArrayList<>();
        try {
            if (wRoutePartList == null || wRoutePartList.size() == 0) {
                return wResult;
            }

            for (FPCRoutePart wFPCRoutePart : wRoutePartList) {
                FPCFlowPart wItem = new FPCFlowPart();

                // ⑥row
                wItem.row = GetRow(wFPCRoutePart, wRoutePartList);
                // ⑦col
                wItem.col = wFPCRoutePart.OrderID;
                // ①id
                wItem.id = String.valueOf(wFPCRoutePart.ID);
                // ②name
                wItem.name = wFPCRoutePart.Name;
                // ③left
                wItem.left = String.valueOf(((wItem.col - 1) * 180 + 20));
                // ④top
                wItem.top = String.valueOf(((wItem.row - 1) * 75 + 35));
                // ⑤showclass
                wItem.showclass = wFPCRoutePart.KeyProcess == 1 ? "mytipshow" : "mytiphide";

                wResult.add(wItem);
            }
        } catch (Exception e) {
            logger.error("GetFlowPartList", e);
        }
        return wResult;
    }

    private int GetRow(FPCRoutePart wItem, List<FPCRoutePart> wRoutePartList) {
        int wResult = 0;
        try {
            List<FPCRoutePart> wList =
                    wRoutePartList.stream().filter(p -> p.OrderID == wItem.OrderID).collect(Collectors.toList());

            for (FPCRoutePart wFPCRoutePart : wList)
                wFPCRoutePart.OrderNumber = 1;

            wList.sort(Comparator.comparing(FPCRoutePart::getOrderNumber, Comparator.reverseOrder()));

            for (int i = 0; i < wList.size(); i++) {
                if (wList.get(i).ID == wItem.ID) {
                    wResult = i + 1;
                    return wResult;
                }
            }
        } catch (Exception e) {
            logger.error("GetRow", e);
        }
        return wResult;
    }

    public List<FPCFlowLine> GetFlowLineList(List<FPCRoutePart> wRoutePartList, List<FPCFlowPart> wFlowPartList) {
        List<FPCFlowLine> wResult = new ArrayList<>();
        try {
            if (wRoutePartList == null || wRoutePartList.size() == 0) {
                return wResult;
            }

            for (FPCRoutePart wFPCRoutePart : wRoutePartList) {
                // ①查询所有后节点
                List<FPCRoutePart> wNextList = wRoutePartList.stream().filter((p -> p.PrevPartID == wFPCRoutePart.ID
                        || wFPCRoutePart.NextPartID.stream().anyMatch(q -> q == p.ID))).collect(Collectors.toList());

                int wRow1 = GetRow(wFPCRoutePart, wRoutePartList);

                for (FPCRoutePart wNextNode : wNextList) {
                    int wRow2 = GetRow(wNextNode, wRoutePartList);

                    FPCFlowLine wFPCFlowLine = new FPCFlowLine();

                    wFPCFlowLine.anode = new FPCFlowPoint();
                    wFPCFlowLine.anode.id = String.valueOf(wFPCRoutePart.ID);
                    wFPCFlowLine.anode.anchor = "Right";
                    wFPCFlowLine.anode.uuid = wFPCFlowLine.anode.id + "_r";

                    wFPCFlowLine.bnode = new FPCFlowPoint();
                    wFPCFlowLine.bnode.id = String.valueOf(wNextNode.ID);
                    wFPCFlowLine.bnode.anchor = "Left";
                    wFPCFlowLine.bnode.uuid = wFPCFlowLine.bnode.id + "_l";

                    // ①a节点和b节点在同一层，列相隔大于1，连上节点
                    if (wRow1 == wRow2 && wNextNode.OrderID - wFPCRoutePart.OrderID > 1) {
                        wFPCFlowLine.anode.anchor = "Top";
                        wFPCFlowLine.anode.uuid = wFPCFlowLine.anode.id + "_t";

                        wFPCFlowLine.bnode.anchor = "Top";
                        wFPCFlowLine.bnode.uuid = wFPCFlowLine.bnode.id + "_t";
                    }
                    // ②a节点层数大于b节点层数，且不存在和A在同一层，且列小于B的工位
                    else if (wRow1 > wRow2 && wFlowPartList.stream().noneMatch(p -> p.row == wRow1
                            && p.col < wNextNode.OrderID && !p.id.equals(String.valueOf(wFPCRoutePart.ID)))) {
                        wFPCFlowLine.anode.anchor = "Right";
                        wFPCFlowLine.anode.uuid = wFPCFlowLine.anode.id + "_r";

                        wFPCFlowLine.bnode.anchor = "Bottom";
                        wFPCFlowLine.bnode.uuid = wFPCFlowLine.bnode.id + "_b";
                    }

                    wResult.add(wFPCFlowLine);
                }
            }
        } catch (Exception e) {
            logger.error("GetFlowLineList", e);
        }
        return wResult;
    }

    public void DeleteList(BMSEmployee wLoginUser, List<FPCRoute> wFPCRouteDelete, OutResult<Integer> wErrorCode) {
        List<String> wResult = new ArrayList<String>();
        try {
            if (wFPCRouteDelete == null || wFPCRouteDelete.size() <= 0) {
                return;
            }

            List<Integer> wIDList = wFPCRouteDelete.stream().map(p -> p.ID).distinct().collect(Collectors.toList());

            String wSQL = StringUtils.Format("DELETE FROM {0}.`fpc_route` WHERE ID IN ({1});",
                    DBSchemas.PDM.getDBName(), StringUtils.Join(",", wIDList));

            Map<String, Object> wParamMap = new HashMap<String, Object>();

            wSQL = this.DMLChange(wSQL);

            this.update(wSQL, wParamMap);
        } catch (Exception ex) {
            logger.error(ex.toString());
        }
    }
}
